﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace TravianLib
{    
    public class Barracks
    {
        public System.Data.DataTable Targets { get; private set; }
        public System.Data.DataRow NextTarget
        {
            get
            {
                System.Data.DataRow output = null;
                while (output == null)
                {
                    if (_targetIndex >= Targets.Rows.Count)
                    {
                        _targetIndex = 0;
                    }
                    Boolean disabled = false;
                    try
                    {
                        disabled = (Boolean)Targets.Rows[_targetIndex]["Disabled"];
                    }
                    catch
                    {
                        Targets.Rows[_targetIndex]["Disabled"] = false;
                    }
                    if (disabled)
                    {
                        _targetIndex++;
                    }
                    else
                    {
                        output = Targets.Rows[_targetIndex];
                    }
                }
                return output;
            }
        }
        
        private int _targetIndex = 0;
        private HTTPFetch _httpFetch = null;
        
        public Barracks(HTTPFetch htf) 
        {
            _httpFetch = htf;
            Targets = new System.Data.DataTable();
            if (System.IO.File.Exists("barracks.xml"))
            {
                Targets.TableName = "PASKA";
                Targets.Columns.Add("x", typeof(int));
                Targets.Columns.Add("y", typeof(int));
                Targets.Columns.Add("Squad Size", typeof(int));
                Targets.Columns.Add("Sent", typeof(int));
                Targets.Columns.Add("Last Attack", typeof(string));
                Targets.Columns.Add("Disabled", typeof(Boolean));
                Targets.ReadXml("barracks.xml");                   
                //Targets.Add(new Point { x = 55, y = 95 });
                //Targets.Add(new Point { x = 54, y = 99 });
                //Targets.Add(new Point { x = 62, y = 95 });
                //Targets.Add(new Point { x = 59, y = 91 });
            }
            if (Targets.Rows.Count > 0)
            {
                _targetIndex = new Random().Next(0, Targets.Rows.Count - 1);
            }
        }
        public List<TimeSpan> Attack(int squadSize)
        {
            return Attack(NextTarget, squadSize);            
        }
        private List<TimeSpan> Attack(System.Data.DataRow point, int squadSize)
        {
            int tmpSquadSize = 0;
            
            List<TimeSpan> outputTs = new List<TimeSpan>();
            int sent = 0;
            int sentPoint = 0;
            if (!int.TryParse(point["Sent"].ToString(), out sentPoint))
            {
                sentPoint = 0;
            }
            string post = "";
            string output = _httpFetch.createHTTPrequest("/a2b.php");
            string basepage = output;
            MatchCollection troopCollection = new Regex("document.snd.t([0-9]+).value=([0-9]+)").Matches(output);            List<KeyValuePair<int, int>> troops = new List<KeyValuePair<int, int>>();
            foreach (Match item in troopCollection)
            {
                troops.Add(new KeyValuePair<int, int>(int.Parse(item.Groups[1].Value), int.Parse(item.Groups[2].Value)));
            }
            int? total = (from c in troops where c.Key == 1 select c.Value).SingleOrDefault();
            if (total == null) total = 0;

            while (sent+1 < total)
            {
                if (!int.TryParse(point["Squad Size"].ToString(), out tmpSquadSize))
                {
                    tmpSquadSize = squadSize;
                }              
                                 
                post = "";
                Regex hiddenfields = new Regex("type=\"hidden\" name=\"(.*?)\" value=\"(.*?)\"");
                foreach (System.Text.RegularExpressions.Match item in hiddenfields.Matches(basepage))
                {
                    post += item.Groups[1].Value + "=" + item.Groups[2].Value + "&";
                }

                post += "t1=" + (tmpSquadSize-sentPoint) +  "&dname=&c=4&x=" + point["x"] + "&y=" + point["y"] + "&s1.x=30&s1.y=" + point["y"] + "&s1=ok";
                output = _httpFetch.createHTTPrequest("/a2b.php", post);

                if (!output.Contains("<p class=\"error\">"))
                {
                    post = "";
                    TimeSpan ts = TimeSpan.Parse(new System.Text.RegularExpressions.Regex("class=\"in\">[A-Za-z ]+(.*?)<").Match(output).Groups[1].Value);
                    foreach (System.Text.RegularExpressions.Match item in hiddenfields.Matches(output))
                    {
                        if (item.Groups[1].Value == "t1")
                        {
                            if (!int.TryParse(point["Sent"].ToString(), out sentPoint))
                            {
                                sentPoint = 0;
                            }
                            sentPoint += int.Parse(item.Groups[2].Value);
                            sent += int.Parse(item.Groups[2].Value);
                        }
                        post += item.Groups[1].Value + "=" + item.Groups[2].Value + "&";
                    }
                    output = _httpFetch.createHTTPrequest("/a2b.php", post);
                    point["Last Attack"] = "OK" + DateTime.Now.ToString("HH:mm");                                    
                    outputTs.Add(ts + new TimeSpan(0, 0, 5));
                    
                }
                else
                {
                    point["Last Attack"] = "Error" + DateTime.Now.ToString("HH:mm") + new Regex("<p class=\"error\">(.*?)<").Match(output).Groups[1].Value;
                    _targetIndex++;
                    point = NextTarget;
                }
                point["Sent"] = sentPoint;
                point.AcceptChanges();
                Targets.AcceptChanges();
                if (sentPoint +1 >= tmpSquadSize)
                {
                    sentPoint = 0;
                    point["Sent"] = sentPoint;
                    _targetIndex++;
                    point = NextTarget;
                }
            }            
            return outputTs;
        }

        ~Barracks()
        {
            Targets.WriteXml("barracks.xml");
        }
    }
}
